package com.example.web.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;

import com.example.web.api.CodeItem;
import com.example.web.bo.Person;
import com.example.web.dao.CallDAO;
import com.outstanding.framework.base.OutstandingService;
import com.outstanding.framework.base.OutstandingTransactionTemplate;
import com.outstanding.framework.core.PendingException;
import com.outstanding.framework.core.SysCode;

/**
 * 事务调用中，被调用方
 * 
 * @author Devin
 *
 */
@Service
public class CalledService extends OutstandingService {

	/**
	 * 嵌套事务
	 */
	@Autowired
	protected OutstandingTransactionTemplate nestedTransactionTemplate;

	/**
	 * 强制事务（需要转移控制权的）
	 */
	@Autowired
	protected OutstandingTransactionTemplate forceTransactionTemplate;

	/**
	 * new事务
	 */
	@Autowired
	protected OutstandingTransactionTemplate newTransactionTemplate;

	public void setNewTransactionTemplate(OutstandingTransactionTemplate newTransactionTemplate) {
		this.newTransactionTemplate = newTransactionTemplate;
	}

	public void setNestedTransactionTemplate(OutstandingTransactionTemplate nestedTransactionTemplate) {
		this.nestedTransactionTemplate = nestedTransactionTemplate;
	}

	public void setForceTransactionTemplate(OutstandingTransactionTemplate forceTransactionTemplate) {
		this.forceTransactionTemplate = forceTransactionTemplate;
	}

	@Autowired
	private CallDAO dao;

	/**
	 * 以下演示同生同死的所有控制权。本方法不回滚，但如果外接回滚后，本方法回滚
	 */

	public void submitForce(final Person p) throws PendingException {

		// 有控制权的
		String result = forceTransactionTemplate.execute(new TransactionCallback<String>() {

			/**
			 * 此方法必须抛出PendingException异常
			 */
			@Override
			public String doInTransaction(TransactionStatus status)throws PendingException {
				int count = 0; // 受影响的行数

				debug("调用submit");
				p.setName("testSubmit");
				count = dao.insert(p);
				if (count == 1) {
					return SysCode.SUCCESS;
				} else {
					status.setRollbackOnly();
					throw new PendingException(CodeItem.T0001, "SQL执行异常"); 
				}

			}
		});

		if (!SysCode.isSuccess(result)) {
			throw new PendingException(result, "SQL执行异常");
		}
	}

	/**
	 * 本方法回滚,且调用方也跟着回滚
	 * 
	 * @param p
	 * @throws PendingException
	 */
	public void rollbackForce(final Person p) throws PendingException {

		// 有控制权的
		String result = forceTransactionTemplate.execute(new TransactionCallback<String>() {

			/**
			 * 此方法必须抛出PendingException异常
			 */
			@Override
			public String doInTransaction(TransactionStatus status) throws PendingException{
				int count = 0; // 受影响的行数

				debug("调用rollerback");
				p.setName("testRollback");
				count = dao.insert(p);
				if (count == 1) {
					status.setRollbackOnly();
					throw new PendingException(CodeItem.T0005, "业务异常");
				} 
				return SysCode.SUCCESS;

			}
		});

		if (!SysCode.isSuccess(result)) {
			throw new PendingException(result, "SQL执行异常");
		}
	}

	/**
	 * 同生同死的所有控制权演示完毕 以下是各自有各自的控制权（对被调用者来说）
	 */

	public void submitNew(final Person p) throws PendingException {

		// 有控制权的
		String result = newTransactionTemplate.execute(new TransactionCallback<String>() {

			/**
			 * 此方法必须抛出PendingException异常
			 */
			@Override
			public String doInTransaction(TransactionStatus status)throws PendingException {
				int count = 0; // 受影响的行数

				debug("调用submit");
				p.setName("testSubmit");
				count = dao.insert(p);
				if (count == 1) {
					return SysCode.SUCCESS;
				} else {
					status.setRollbackOnly();
					throw new PendingException(CodeItem.T0001, "SQL执行异常"); 
				}

			}
		});

		if (!SysCode.isSuccess(result)) {
			throw new PendingException(result, "SQL执行异常");
		}
	}

	/**
	 * 本方法回滚,调用方进行判断，可以回滚，也可以不回滚
	 * 
	 * @param p
	 * @throws PendingException
	 */
	public void rollbackNew(final Person p) throws PendingException {

		// 有控制权的
		String result = newTransactionTemplate.execute(new TransactionCallback<String>() {

			/**
			 * 此方法必须抛出PendingException异常
			 */
			@Override
			public String doInTransaction(TransactionStatus status) throws PendingException{
				int count = 0; // 受影响的行数

				debug("调用rollerback");
				p.setName("testRollback");
				count = dao.insert(p);
				if (count == 1) {
					status.setRollbackOnly();
					throw new PendingException(CodeItem.T0005, "业务异常");
				}
				return SysCode.SUCCESS;

			}
		});

		if (!SysCode.isSuccess(result)) {
			throw new PendingException(result, "SQL执行异常");
		}
	}

	/**
	 * 各自有各自的控制权演示完毕 以下是合并（合并对调用者来说是交出了完全控制权）但不交出完全的控制权（对被调用者来说）
	 */

	public void submitNested(final Person p) throws PendingException {

		// 有控制权的
		String result = nestedTransactionTemplate.execute(new TransactionCallback<String>() {

			/**
			 * 此方法必须抛出PendingException异常
			 */
			@Override
			public String doInTransaction(TransactionStatus status) throws PendingException{
				int count = 0; // 受影响的行数

				debug("调用submit");
				p.setName("testSubmit");
				count = dao.insert(p);
				if (count == 1) {
					return SysCode.SUCCESS;
				} else {
					status.setRollbackOnly();
					throw new PendingException(CodeItem.T0001, "SQL执行异常"); 
				}

			}
		});

		if (!SysCode.isSuccess(result)) {
			throw new PendingException(result, "SQL执行异常");
		}
	}

	/**
	 * 本方法回滚,且调用方也跟着回滚
	 * 
	 * @param p
	 * @throws PendingException
	 */
	public void rollbackNested(final Person p) throws PendingException {

		// 有控制权的
		String result = nestedTransactionTemplate.execute(new TransactionCallback<String>() {

			/**
			 * 此方法必须抛出PendingException异常
			 */
			@Override
			public String doInTransaction(TransactionStatus status) throws PendingException{
				int count = 0; // 受影响的行数

				debug("调用rollerback");
				p.setName("testRollback");
				count = dao.insert(p);

				if (count == 1) {
					throw new PendingException(CodeItem.T0005, "业务异常");
				}
				return SysCode.SUCCESS;

			}
		});

		if (!SysCode.isSuccess(result)) {
			throw new PendingException(result, "SQL执行异常");
		}
	}
}
